#include "Common.h"
#include "SystemV/AppLibSystemV_Sem.hpp"

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
    
/**********************************************************
 * Function Name:        AppLibSystemV_SemCreate
 * Description:          信号量初始化
 * Parameters[in]:       IN CHAR *pcFilePath
 *                       IN SINT32 nsems
 *                       INOUT SINT32 *piSemId
 * Parameters[out]:      INOUT SINT32 *piSemId
 * ReturnValue:          ULONG
 * Author:               liuke
 * Date:                 2024.10.28
***********************************************************/
ULONG AppLibSystemV_SemCreate(IN CHAR *pcFilePath, IN SINT32 nsems, INOUT SINT32 *piSemId)
{
    SINT32 iFd = 0;

    if ((pcFilePath == NULL) || (piSemId == NULL))
    {
        LOG_ERROR("err: pcFilePath=%p piSemId=%p\n", pcFilePath, piSemId);
        return STAT_ERR_INVAILD_PARAM;
    }

    iFd = AppLibSystemV_Get(APP_LIB_SYSTEM_V_TYPE_SEM, pcFilePath, nsems);
    if(iFd < 0)
    {
        LOG_ERROR("err %d [%s]\n", errno, strerror(errno));
        return STAT_ERR_SYSTEM_V_SEM_GET;
    }

    *piSemId = iFd;

    return STAT_SUCCESS;
}

/**********************************************************
 * Function Name:        SystemV_Sem_Destory
 * Description:          消息注销
 * Parameters[in]:       INOUT SINT32 *piSemId
 * Parameters[out]:      INOUT SINT32 *piSemId
 * ReturnValue:          ULONG
 * Author:               liuke
 * Date:                 2024.10.28
***********************************************************/
ULONG AppLibSystemV_SemDestory(INOUT SINT32 *piSemId)
{
    ULONG ulRet = STAT_SUCCESS;

    if ((piSemId == NULL) || (*piSemId < 0))
    {
        LOG_ERROR("Sem already destory\n");
        return STAT_ERR_INVAILD_PARAM;
    }

    ulRet = AppLibSystemV_Ctl(APP_LIB_SYSTEM_V_TYPE_SEM, *piSemId, IPC_RMID, NULL);
    if (ulRet != STAT_SUCCESS)
    {
        return ulRet;
    }

    *piSemId = -1;

    return ulRet;
}

/**********************************************************
 * Function Name:        SystemV_Sem_SetVal
 * Description:          信号量初始化某个信号初始值
 * Parameters[in]:       IN SINT32 iSemId
 *                       IN SINT32 iSemNum
 *                       IN SINT32 Val
 * Parameters[out]:      
 * ReturnValue:          ULONG
 * Author:               liuke
 * Date:                 2024.10.28
***********************************************************/
ULONG AppLibSystemV_SemSetVal(IN SINT32 iSemId, IN SINT32 iSemNum, IN SINT32 Val)
{
    return AppLibSystemV_Ctl(APP_LIB_SYSTEM_V_TYPE_SEM, iSemId, iSemNum, SETVAL, Val);;
}

/**********************************************************
 * Function Name:        SystemV_Sem_P
 * Description:          信号量执行减操作
 * Parameters[in]:       IN SINT32 iSemId
 *                       IN SINT32 iSemNum
 * Parameters[out]:      
 * ReturnValue:          ULONG
 * Author:               liuke
 * Date:                 2024.10.28
***********************************************************/
ULONG AppLibSystemV_SemP(IN SINT32 iSemId, IN SINT32 iSemNum)
{
    return AppLibSystemV_SemCtrl(iSemId, iSemNum, APP_LIB_SYSTEM_V_SEM_OP_P);
}

/**********************************************************
 * Function Name:        SystemV_Sem_P_Wait
 * Description:          信号量执行阻塞式减操作
 * Parameters[in]:       IN SINT32 iSemId
 *                       IN SINT32 iSemNum
 * Parameters[out]:      
 * ReturnValue:          ULONG
 * Author:               liuke
 * Date:                 2024.10.28
***********************************************************/
ULONG AppLibSystemV_SemP_Wait(IN SINT32 iSemId, IN SINT32 iSemNum)
{
    return AppLibSystemV_SemCtrl(iSemId, iSemNum, APP_LIB_SYSTEM_V_SEM_OP_P_BLOCK);
}

/**********************************************************
 * Function Name:        SystemV_Sem_V
 * Description:          信号量执行加操作
 * Parameters[in]:       IN SINT32 iSemId
 *                       IN SINT32 iSemNum
 * Parameters[out]:      
 * ReturnValue:          ULONG
 * Author:               liuke
 * Date:                 2024.10.28
***********************************************************/
ULONG AppLibSystemV_SemV(IN SINT32 iSemId, IN SINT32 iSemNum)
{
    return AppLibSystemV_SemCtrl(iSemId, iSemNum, APP_LIB_SYSTEM_V_SEM_OP_V);
}

/**********************************************************
 * Function Name:        SystemV_Sem_V_Wait
 * Description:          信号量执行阻塞式加操作
 * Parameters[in]:       IN SINT32 iSemId
 *                       IN SINT32 iSemNum
 * Parameters[out]:      
 * ReturnValue:          ULONG
 * Author:               liuke
 * Date:                 2024.10.28
***********************************************************/
ULONG AppLibSystemV_SemV_Wait(IN SINT32 iSemId, IN SINT32 iSemNum)
{
    return AppLibSystemV_SemCtrl(iSemId, iSemNum, APP_LIB_SYSTEM_V_SEM_OP_V_BLOCK);
}